const path = require('path')
// 压缩js代码 https://www.npmjs.com/package/uglifyjs-webpack-plugin
// 2.x以上不支持在 compress 中配置 wrning，可以使用 warningsFilter 来去除警告
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
// 将大的文件压缩为压缩包 https://webpack.docschina.org/plugins/compression-webpack-plugin/#test
// 前端将压缩文件配置了，但是得需要后端支持压缩。。目前只是前端将文件压缩。可关闭配置
// NOTE: 使用 7.1.2 版本打包会报错。 Cannot read property 'tapPromise' of undefined。将版本降低为 5.0.1
const CompressionPlugin = require('compression-webpack-plugin')
// 默认使用 gzip 压缩
const compressionPluginOptions = new CompressionPlugin({
  // 压缩 js/html/css 文件
  test: /\.js$|\.html$|\.css/,
  threshold: 20480,  // 超过 20480 被压缩
  deleteOriginalAssets: false // 是否删除源文件
})

const resolve = dir => path.join(__dirname, dir)
// 判断是否为 prod
const isProd = process.env.NODE_ENV === 'production'

const addStyleResource = rule => {
  // 在每个单文件组件中和scss中 引入全局样式 index.scss
  rule.use('style-resource')
    .loader('style-resources-loader')
    .options({
      patterns: [ path.resolve(__dirname, './src/assets/scss/index.scss') ]
    })
}

const filterNames = ['manifest', 'vendor', 'app']

module.exports = {
  devServer: {
    proxy: {
      '/example-api': {
        target: 'http://localhost:8800',
        changeOrigin: true,
        pathRewrite: {
          '/example-api': '/api'
        }
      },
      '/*-api': {
        target: 'https://2405.rc-dev-test.ywsoftware.cn:9443',
        changeOrigin: true
      }
    }
  },
  chainWebpack: config => {
    // copy插件 https://webpack.docschina.org/plugins/copy-webpack-plugin/ 因为这个插件是内置的，所以不需要安装
    if (config.plugins.has('copy')) {
      config.plugin('copy')
      // 给默认options新增两个copy
        .tap(options => [[
          ...options[0],
          { from: 'node_modules/redcat-app/dist' },
          { from: 'node_modules/redcat-app-sdk/dist', to: 'js' }
        ]])
    }
    // 配置别名
    config.resolve.alias
      .set('@', resolve('./src'))
      .set('@utils', resolve('./src/utils/index.js'))
      .set('@views', resolve('./src/views'))

    // 配置将小于20k的图片转换为base64
    config.module
      .rule('images') // 配置images rule
      .use('url-loader') // 使用 url-loader
      .tap(options => Object.assign(options, { limit: 20480 })) // 配置options，将 limit 修改为 20480

    // 配置插件将全局scss引入 style-resources-loader：自动化导入 https://github.com/yenshih/style-resources-loader
    const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
    types.forEach(type => addStyleResource(config.module.rule('scss').oneOf(type)))
  },
  productionSourceMap: false,
  css: {
    // 是否启用css分离插件 ExtractTextPlugin 生产环境不需要css文件，强制内联
    extract: !isProd,
    // 不开启 css soruce map
    sourceMap: false
  },
  configureWebpack: config => {
    // 为生产环境配置
    if (isProd) {
      // 配置插件
      config.plugins.push(
        new UglifyJsPlugin({
          // UglifyJS 压缩选项
          uglifyOptions: {
            // 删除注释
            output: {
              comments: false
            },
            // 删除 console debugger warning
            compress: {
              // 如果需要查看 console.log 打包的之前可以将这个值设置为 false
              drop_console: true,
              drop_debugger: true
            }
          },
          // 启用/禁用多进程并行运行。
          parallel: true,
          // 使用sourceMap将错误消息位置映射到模块(这会减慢编译速度)。如果您使用自己的minify函数，请阅读minify部分以正确处理sourceMap。
          sourceMap: false,
          // 去除警告
          warningsFilter: () => false
        })
      )
      // NOTE: 如果不需要配置压缩将这段代码注释即可
      config.plugins.push(compressionPluginOptions)
    } else {
      // 为开发环境配置
    }
    // 配置 externals 设置 externals 为了阻止将包打包，而是在运行到时候通过外部去获取这个包
    config.externals = {
      // 文档：https://webpack.js.org/configuration/externals/
      // redcat-app-sdk暴露的全局变量为 redcatSdk
      // import sdk from 'sdk' 相当于是拿到 redcat-app-sdk 暴露的全局变量 redcatSdk
      // 'sdk': 'redcatSdk
      'redcatSdk': 'redcatSdk'
    }
    // 引入平台项目会导致报错 TypeError: (intermediate value)(intermediate value).push is not a function
    config.optimization = {
      splitChunks: {
        chunks (chunk) {
          // 不优化平台项目导入的块
          return !filterNames.includes(chunk.name)
        }
      }
    }
  }
}
